home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / ser-tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  6.7 KB  |  317 lines

  1. /* Serial interface for raw TCP connections on Un*x like systems
  2.    Copyright 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "serial.h"
  22. #include <sys/types.h>
  23. #include <sys/time.h>
  24. #include <netinet/in.h>
  25. #include <arpa/inet.h>
  26. #include <netdb.h>
  27. #include <sys/socket.h>
  28. #include <netinet/tcp.h>
  29. #include "signals.h"
  30.  
  31. struct tcp_ttystate
  32. {
  33.   int bogus;
  34. };
  35.  
  36. static int tcp_open PARAMS ((serial_t scb, const char *name));
  37. static void tcp_raw PARAMS ((serial_t scb));
  38. static int wait_for PARAMS ((serial_t scb, int timeout));
  39. static int tcp_readchar PARAMS ((serial_t scb, int timeout));
  40. static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
  41. static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
  42. /* FIXME: static void tcp_restore PARAMS ((serial_t scb)); */
  43. static void tcp_close PARAMS ((serial_t scb));
  44. static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
  45. static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
  46.  
  47. /* Open up a raw tcp socket */
  48.  
  49. static int
  50. tcp_open(scb, name)
  51.      serial_t scb;
  52.      const char *name;
  53. {
  54.   char *port_str;
  55.   int port;
  56.   struct hostent *hostent;
  57.   struct sockaddr_in sockaddr;
  58.   int tmp;
  59.   char hostname[100];
  60.   struct protoent *protoent;
  61.  
  62.   port_str = strchr (name, ':');
  63.  
  64.   if (!port_str)
  65.     error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
  66.  
  67.   tmp = min (port_str - name, sizeof hostname - 1);
  68.   strncpy (hostname, name, tmp); /* Don't want colon */
  69.   hostname[tmp] = '\000';    /* Tie off host name */
  70.   port = atoi (port_str + 1);
  71.  
  72.   hostent = gethostbyname (hostname);
  73.  
  74.   if (!hostent)
  75.     {
  76.       fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
  77.       errno = ENOENT;
  78.       return -1;
  79.     }
  80.  
  81.   scb->fd = socket (PF_INET, SOCK_STREAM, 0);
  82.   if (scb->fd < 0)
  83.     return -1;
  84.  
  85.   /* Allow rapid reuse of this port. */
  86.   tmp = 1;
  87.   setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
  88.  
  89.   /* Enable TCP keep alive process. */
  90.   tmp = 1;
  91.   setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
  92.  
  93.   sockaddr.sin_family = PF_INET;
  94.   sockaddr.sin_port = htons(port);
  95.   memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
  96.       sizeof (struct in_addr));
  97.  
  98.   if (connect (scb->fd, &sockaddr, sizeof(sockaddr)))
  99.     {
  100.       close(scb->fd);
  101.       scb->fd = -1;
  102.       return -1;
  103.     }
  104.  
  105.   protoent = getprotobyname ("tcp");
  106.   if (!protoent)
  107.     return -1;
  108.  
  109.   tmp = 1;
  110.   if (setsockopt (scb->fd, protoent->p_proto, TCP_NODELAY,
  111.           (char *)&tmp, sizeof(tmp)))
  112.     return -1;
  113.  
  114.   signal(SIGPIPE, SIG_IGN);    /* If we don't do this, then GDB simply exits
  115.                    when the remote side dies.  */
  116.  
  117.   return 0;
  118. }
  119.  
  120. static serial_ttystate
  121. tcp_get_tty_state(scb)
  122.      serial_t scb;
  123. {
  124.   struct tcp_ttystate *state;
  125.  
  126.   state = (struct tcp_ttystate *)xmalloc(sizeof *state);
  127.  
  128.   return (serial_ttystate)state;
  129. }
  130.  
  131. static int
  132. tcp_set_tty_state(scb, ttystate)
  133.      serial_t scb;
  134.      serial_ttystate ttystate;
  135. {
  136.   struct tcp_ttystate *state;
  137.  
  138.   state = (struct tcp_ttystate *)ttystate;
  139.  
  140.   return 0;
  141. }
  142.  
  143. static int
  144. tcp_return_0 (scb)
  145.      serial_t scb;
  146. {
  147.   return 0;
  148. }
  149.  
  150. static void
  151. tcp_raw(scb)
  152.      serial_t scb;
  153. {
  154.   return;            /* Always in raw mode */
  155. }
  156.  
  157. /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
  158.    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
  159.  
  160.    For termio{s}, we actually just setup VTIME if necessary, and let the
  161.    timeout occur in the read() in tcp_read().
  162.  */
  163.  
  164. static int
  165. wait_for(scb, timeout)
  166.      serial_t scb;
  167.      int timeout;
  168. {
  169.   int numfds;
  170.   struct timeval tv;
  171.   fd_set readfds, exceptfds;
  172.  
  173.   FD_ZERO (&readfds);
  174.   FD_ZERO (&exceptfds);
  175.  
  176.   tv.tv_sec = timeout;
  177.   tv.tv_usec = 0;
  178.  
  179.   FD_SET(scb->fd, &readfds);
  180.   FD_SET(scb->fd, &exceptfds);
  181.  
  182.   while (1)
  183.     {
  184.       if (timeout >= 0)
  185.     numfds = select(scb->fd+1, &readfds, 0, &exceptfds, &tv);
  186.       else
  187.     numfds = select(scb->fd+1, &readfds, 0, &exceptfds, 0);
  188.  
  189.       if (numfds <= 0)
  190.     if (numfds == 0)
  191.       return SERIAL_TIMEOUT;
  192.     else if (errno == EINTR)
  193.       continue;
  194.     else
  195.       return SERIAL_ERROR;    /* Got an error from select or poll */
  196.  
  197.       return 0;
  198.     }
  199. }
  200.  
  201. /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
  202.    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
  203.    char if successful.  Returns -2 if timeout expired, EOF if line dropped
  204.    dead, or -3 for any other error (see errno in that case). */
  205.  
  206. static int
  207. tcp_readchar(scb, timeout)
  208.      serial_t scb;
  209.      int timeout;
  210. {
  211.   int status;
  212.  
  213.   if (scb->bufcnt-- > 0)
  214.     return *scb->bufp++;
  215.  
  216.   status = wait_for(scb, timeout);
  217.  
  218.   if (status < 0)
  219.     return status;
  220.  
  221.   scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
  222.  
  223.   if (scb->bufcnt <= 0)
  224.     if (scb->bufcnt == 0)
  225.       return SERIAL_TIMEOUT;    /* 0 chars means timeout [may need to
  226.                    distinguish between EOF & timeouts
  227.                    someday] */
  228.     else
  229.       return SERIAL_ERROR;    /* Got an error from read */
  230.  
  231.   scb->bufcnt--;
  232.   scb->bufp = scb->buf;
  233.   return *scb->bufp++;
  234. }
  235.  
  236. static int
  237. tcp_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
  238.      serial_t scb;
  239.      serial_ttystate new_ttystate;
  240.      serial_ttystate old_ttystate;
  241. {
  242.   return 0;
  243. }
  244.  
  245. static void
  246. tcp_print_tty_state (scb, ttystate)
  247.      serial_t scb;
  248.      serial_ttystate ttystate;
  249. {
  250.   /* Nothing to print.  */
  251.   return;
  252. }
  253.  
  254. static int
  255. tcp_setbaudrate(scb, rate)
  256.      serial_t scb;
  257.      int rate;
  258. {
  259.   return 0;            /* Never fails! */
  260. }
  261.  
  262. static int
  263. tcp_write(scb, str, len)
  264.      serial_t scb;
  265.      const char *str;
  266.      int len;
  267. {
  268.   int cc;
  269.  
  270.   while (len > 0)
  271.     {
  272.       cc = write(scb->fd, str, len);
  273.  
  274.       if (cc < 0)
  275.     return 1;
  276.       len -= cc;
  277.       str += cc;
  278.     }
  279.   return 0;
  280. }
  281.  
  282. static void
  283. tcp_close(scb)
  284.      serial_t scb;
  285. {
  286.   if (scb->fd < 0)
  287.     return;
  288.  
  289.   close(scb->fd);
  290.   scb->fd = -1;
  291. }
  292.  
  293. static struct serial_ops tcp_ops =
  294. {
  295.   "tcp",
  296.   0,
  297.   tcp_open,
  298.   tcp_close,
  299.   tcp_readchar,
  300.   tcp_write,
  301.   tcp_return_0, /* flush output */
  302.   tcp_return_0, /* flush input */
  303.   tcp_return_0, /* send break */
  304.   tcp_raw,
  305.   tcp_get_tty_state,
  306.   tcp_set_tty_state,
  307.   tcp_print_tty_state,
  308.   tcp_noflush_set_tty_state,
  309.   tcp_setbaudrate,
  310. };
  311.  
  312. void
  313. _initialize_ser_tcp ()
  314. {
  315.   serial_add_interface (&tcp_ops);
  316. }
  317.